<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MQTT连接测试</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background: #f5f5f5;
        }
        .container {
            background: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .test-section {
            margin: 20px 0;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .btn {
            padding: 10px 20px;
            margin: 5px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        .btn-primary {
            background: #007bff;
            color: white;
        }
        .btn-success {
            background: #28a745;
            color: white;
        }
        .btn-danger {
            background: #dc3545;
            color: white;
        }
        .log {
            background: #f8f9fa;
            border: 1px solid #e9ecef;
            border-radius: 5px;
            padding: 10px;
            height: 200px;
            overflow-y: auto;
            font-family: monospace;
            font-size: 12px;
        }
        .status {
            padding: 10px;
            margin: 10px 0;
            border-radius: 5px;
        }
        .status.success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        .status.error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        .status.info {
            background: #d1ecf1;
            color: #0c5460;
            border: 1px solid #bee5eb;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>MQTT连接测试</h1>
        
        <div class="test-section">
            <h3>基础连接测试</h3>
            <p>测试EMQX公共Broker: <code>mqtt://broker.emqx.io:1883</code></p>
            <button class="btn btn-primary" onclick="testBasicConnection()">测试基础连接</button>
            <button class="btn btn-success" onclick="testWithAuth()">测试认证连接</button>
        </div>

        <div class="test-section">
            <h3>自定义连接测试</h3>
            <div>
                <label>Broker地址:</label>
                <input type="text" id="brokerUrl" value="mqtt://broker.emqx.io:1883" style="width: 300px; padding: 5px;">
            </div>
            <div style="margin-top: 10px;">
                <label>用户名:</label>
                <input type="text" id="username" placeholder="可选" style="width: 150px; padding: 5px;">
                <label style="margin-left: 10px;">密码:</label>
                <input type="password" id="password" placeholder="可选" style="width: 150px; padding: 5px;">
            </div>
            <button class="btn btn-primary" onclick="testCustomConnection()" style="margin-top: 10px;">测试自定义连接</button>
        </div>

        <div class="test-section">
            <h3>测试结果</h3>
            <div id="status" class="status info">准备测试...</div>
            <div class="log" id="log"></div>
        </div>

        <div class="test-section">
            <h3>MQTT.js库状态</h3>
            <button class="btn btn-info" onclick="checkMQTTStatus()">检查MQTT.js状态</button>
            <button class="btn btn-danger" onclick="clearLog()">清空日志</button>
        </div>
    </div>

    <script>
        let mqttClient = null;

        function log(message, type = 'info') {
            const logElement = document.getElementById('log');
            const timestamp = new Date().toLocaleTimeString();
            const logEntry = document.createElement('div');
            logEntry.innerHTML = `<span style="color: #666;">[${timestamp}]</span> ${message}`;
            
            if (type === 'error') {
                logEntry.style.color = '#dc3545';
            } else if (type === 'success') {
                logEntry.style.color = '#28a745';
            }
            
            logElement.appendChild(logEntry);
            logElement.scrollTop = logElement.scrollHeight;
        }

        function setStatus(message, type = 'info') {
            const statusElement = document.getElementById('status');
            statusElement.textContent = message;
            statusElement.className = `status ${type}`;
        }

        function clearLog() {
            document.getElementById('log').innerHTML = '';
            setStatus('日志已清空', 'info');
        }

        function checkMQTTStatus() {
            if (typeof mqtt === 'undefined') {
                setStatus('MQTT.js未加载', 'error');
                log('正在加载MQTT.js...', 'info');
                
                const script = document.createElement('script');
                script.src = 'https://unpkg.com/mqtt@4.3.7/dist/mqtt.min.js';
                script.onload = function() {
                    setStatus('MQTT.js加载成功', 'success');
                    log('✓ MQTT.js库加载成功', 'success');
                    log(`MQTT版本: ${mqtt?.version || '未知'}`);
                };
                script.onerror = function() {
                    setStatus('MQTT.js加载失败', 'error');
                    log('✗ MQTT.js库加载失败', 'error');
                };
                document.head.appendChild(script);
            } else {
                setStatus('MQTT.js已加载', 'success');
                log(`✓ MQTT.js已加载 (版本: ${mqtt?.version || '未知'})`, 'success');
            }
        }

        async function testBasicConnection() {
            setStatus('正在测试基础连接...', 'info');
            log('开始测试基础连接到 broker.emqx.io:1883', 'info');
            
            await testMQTTConnection('mqtt://broker.emqx.io:1883', '', '');
        }

        async function testWithAuth() {
            setStatus('正在测试认证连接...', 'info');
            log('开始测试认证连接到 broker.emqx.io:1883', 'info');
            
            // 使用EMQX测试账号
            await testMQTTConnection('mqtt://broker.emqx.io:1883', 'emqx_test', 'emqx_test');
        }

        async function testCustomConnection() {
            const brokerUrl = document.getElementById('brokerUrl').value.trim();
            const username = document.getElementById('username').value.trim();
            const password = document.getElementById('password').value.trim();
            
            if (!brokerUrl) {
                setStatus('请输入Broker地址', 'error');
                return;
            }
            
            setStatus('正在测试自定义连接...', 'info');
            log(`开始测试连接到: ${brokerUrl}`, 'info');
            
            await testMQTTConnection(brokerUrl, username, password);
        }

        async function testMQTTConnection(brokerUrl, username, password) {
            // 确保MQTT.js已加载
            if (typeof mqtt === 'undefined') {
                setStatus('请先加载MQTT.js库', 'error');
                log('✗ MQTT.js库未加载，请点击"检查MQTT.js状态"', 'error');
                return false;
            }

            try {
                // 清理之前的连接
                if (mqttClient) {
                    mqttClient.end();
                    mqttClient = null;
                }

                const options = {
                    clientId: 'test_' + Math.random().toString(16).substr(2, 8),
                    clean: true,
                    connectTimeout: 8000,
                    reconnectPeriod: 0
                };

                if (username) {
                    options.username = username;
                    if (password) {
                        options.password = password;
                    }
                }

                log(`连接选项: ${JSON.stringify(options)}`, 'info');
                
                mqttClient = mqtt.connect(brokerUrl, options);

                return new Promise((resolve) => {
                    const timeout = setTimeout(() => {
                        if (mqttClient) {
                            mqttClient.end();
                            mqttClient = null;
                        }
                        setStatus('连接超时', 'error');
                        log('✗ 连接超时 (8秒)', 'error');
                        resolve(false);
                    }, 10000);

                    mqttClient.on('connect', () => {
                        clearTimeout(timeout);
                        setStatus('连接成功!', 'success');
                        log('✓ MQTT连接成功', 'success');
                        
                        // 测试发布消息
                        testPublishMessage();
                        
                        resolve(true);
                    });

                    mqttClient.on('error', (error) => {
                        clearTimeout(timeout);
                        setStatus('连接失败', 'error');
                        log(`✗ 连接错误: ${error.message}`, 'error');
                        
                        // 详细错误诊断
                        diagnoseConnectionError(error, brokerUrl);
                        
                        resolve(false);
                    });

                    mqttClient.on('close', () => {
                        log('连接已关闭', 'info');
                    });
                });

            } catch (error) {
                setStatus('连接异常', 'error');
                log(`✗ 连接异常: ${error.message}`, 'error');
                return false;
            }
        }

        function testPublishMessage() {
            if (!mqttClient || !mqttClient.connected) return;
            
            const testTopic = '/test/mqtt/web';
            const testPayload = JSON.stringify({
                message: 'Hello from MQTT Web Test',
                timestamp: new Date().toISOString(),
                clientId: mqttClient.options.clientId
            });

            mqttClient.publish(testTopic, testPayload, { qos: 0 }, (error) => {
                if (error) {
                    log(`✗ 消息发布失败: ${error.message}`, 'error');
                } else {
                    log(`✓ 消息发布成功: ${testPayload}`, 'success');
                }
            });
        }

        function diagnoseConnectionError(error, brokerUrl) {
            const errorMsg = error.message || error.toString();
            
            if (errorMsg.includes('Network Error') || errorMsg.includes('CORS')) {
                log('诊断: 可能是CORS跨域问题，尝试使用WebSocket协议', 'info');
                log('建议: 使用 ws://broker.emqx.io:8083/mqtt', 'info');
            } else if (errorMsg.includes('UNAUTHORIZED')) {
                log('诊断: 认证失败，请检查用户名和密码', 'info');
            } else if (errorMsg.includes('ENOTFOUND')) {
                log('诊断: 无法解析主机名，请检查网络连接', 'info');
            } else if (errorMsg.includes('ECONNREFUSED')) {
                log('诊断: 连接被拒绝，Broker可能未运行或端口错误', 'info');
            }
        }

        // 页面加载时检查MQTT状态
        window.addEventListener('load', function() {
            setTimeout(checkMQTTStatus, 100);
        });
    </script>
</body>
</html>